package com.engine.kq.cmd.report;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.kq.biz.*;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.util.ExcelUtil;
import com.engine.kq.util.KQDurationCalculatorUtil;
import com.engine.kq.util.UtilKQ;
import com.engine.qz.util.QzUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import weaver.common.DateUtil;
import weaver.common.StringUtil;
import weaver.conn.RecordSet;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.company.SubCompanyComInfo;
import weaver.hrm.job.JobTitlesComInfo;
import weaver.hrm.report.schedulediff.HrmScheduleDiffUtil;
import weaver.hrm.resource.ResourceComInfo;
import weaver.systeminfo.SystemEnv;
import com.google.common.collect.Lists;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class ExportExcelCmd extends AbstractCommonCommand<Map<String, Object>> {

  private HttpServletRequest request;
  private HttpServletResponse response;
  private List<String> lsFieldDataKey;

  private boolean isKqReportHalfOpen = "1".equals(new KQSettingsComInfo().getMain_val("kq_report_half"));

  public ExportExcelCmd(Map<String, Object> params, HttpServletRequest request, HttpServletResponse response, User user) {
    this.user = user;
    this.params = params;
    this.request = request;
    this.response = response;
    this.lsFieldDataKey = new ArrayList<>();
  }

  @Override
  public Map<String, Object> execute(CommandContext commandContext) {
    Map<String, Object> retmap = new HashMap<String, Object>();
    RecordSet rs = new RecordSet();
    String sql = "";
    try {
      SubCompanyComInfo subCompanyComInfo = new SubCompanyComInfo();
      DepartmentComInfo departmentComInfo = new DepartmentComInfo();
      ResourceComInfo resourceComInfo = new ResourceComInfo();
      JobTitlesComInfo jobTitlesComInfo = new JobTitlesComInfo();
      KQLeaveRulesBiz kqLeaveRulesBiz = new KQLeaveRulesBiz();
      KQSettingsComInfo kqSettingsComInfo = new KQSettingsComInfo();
      String leavetype_is_on = Util.null2String(kqSettingsComInfo.getMain_val("leavetype_is_on"),"0");

      KQReportBiz kqReportBiz = new KQReportBiz();
      new KQReportBiz().insertKqReportExportLog(params, user);
      JSONObject jsonObj = JSON.parseObject(Util.null2String(params.get("data")));
      String attendanceSerial = Util.null2String(jsonObj.get("attendanceSerial"));
      String fromDate = Util.null2String(jsonObj.get("fromDate"));
      String toDate = Util.null2String(jsonObj.get("toDate"));
      String typeselect = Util.null2String(jsonObj.get("typeselect"));
      if (typeselect.length() == 0) typeselect = "3";
      if (!typeselect.equals("") && !typeselect.equals("0") && !typeselect.equals("6")) {
        if (typeselect.equals("1")) {
          fromDate = TimeUtil.getCurrentDateString();
          toDate = TimeUtil.getCurrentDateString();
        } else {
          fromDate = TimeUtil.getDateByOption(typeselect, "0");
          toDate = TimeUtil.getDateByOption(typeselect, "1");
        }
      }
      //人员状态
      String status = Util.null2String(jsonObj.get("status"));
      String subCompanyId = Util.null2String(jsonObj.get("subCompanyId"));
      String departmentId = Util.null2String(jsonObj.get("departmentId"));
      String resourceId = Util.null2String(jsonObj.get("resourceId"));
      String allLevel = Util.null2String(jsonObj.get("allLevel"));
      String isNoAccount = Util.null2String(jsonObj.get("isNoAccount"));
      String viewScope = Util.null2String(jsonObj.get("viewScope"));
      List<String> showColumns = Util.splitString2List(Util.null2String(jsonObj.get("showColumns")), ",");
      showColumns.add("lastname");
      showColumns.removeIf(showColumn->showColumn.trim().equals(""));

      List<String> tmpShowColumns = new ArrayList<>();
      for(String showColumn:showColumns){
        tmpShowColumns.add(showColumn);
        String cascadekey = "";
        if(showColumn.equals("beLate")){
          cascadekey = "beLateMins";
        }else if(showColumn.equals("leaveEearly")){
          cascadekey = "leaveEarlyMins";
        }else if(showColumn.equals("graveBeLate")){
          cascadekey = "graveBeLateMins";
        }else if(showColumn.equals("graveLeaveEarly")){
          cascadekey = "graveLeaveEarlyMins";
        }else if(showColumn.equals("absenteeism")){
          cascadekey = "absenteeismMins";
        }else if(showColumn.equals("overtime")){
          tmpShowColumns.add("overtime_4leave");
          tmpShowColumns.add("overtime_nonleave");
          tmpShowColumns.add("workingDayOvertime_nonleave");
          tmpShowColumns.add("workingDayOvertime_4leave");
          tmpShowColumns.add("restDayOvertime_nonleave");
          tmpShowColumns.add("restDayOvertime_4leave");
          tmpShowColumns.add("holidayOvertime_4leave");
          tmpShowColumns.add("holidayOvertime_nonleave");
        }
        if(cascadekey.length()>0){
          tmpShowColumns.add(cascadekey);
        }
      }
      showColumns = tmpShowColumns;

      String rightSql = new KQReportBiz().getReportRight("1", "" + user.getUID(), "a");

      LinkedHashMap<String, Object> workbook = new LinkedHashMap<>();
      List<Object> lsSheet = new ArrayList<>();
      Map<String, Object> sheet = null;
      List<Object> titleList = new ArrayList<>();
      Map<String, Object> title = null;
      List<List<Object>> dataList = new ArrayList<>();
      List<Object> data = null;
      List<Map<String, Object>> constraintList = null;

      sheet = new HashMap<>();
      sheet.put("sheetName", SystemEnv.getHtmlLabelName(390351, user.getLanguage()));
      sheet.put("sheetTitle", SystemEnv.getHtmlLabelName(390351, user.getLanguage()));
      boolean isEnd = false;
      Calendar cal = DateUtil.getCalendar();

      List<Map<String, Object>> leaveRules = kqLeaveRulesBiz.getAllLeaveRules();
      Map<String, Object> mapChildColumnInfo = null;
      List<Object> childColumns = null;
      KQReportFieldComInfo kqReportFieldComInfo = new KQReportFieldComInfo();
      while (kqReportFieldComInfo.next()) {
        if (Util.null2String(kqReportFieldComInfo.getParentid()).length() > 0) continue;
        if(kqReportFieldComInfo.getFieldname().equals("kqCalendar"))continue;
        if(KQReportFieldComInfo.cascadekey2fieldname.keySet().contains(kqReportFieldComInfo.getFieldname()))continue;
        if (!kqReportFieldComInfo.getReportType().equals("all") && !kqReportFieldComInfo.getReportType().equals("month"))
          continue;
        if (!showColumns.contains(kqReportFieldComInfo.getFieldname())&&!showColumns.contains(kqReportFieldComInfo.getParentid())) continue;
        if("leave".equalsIgnoreCase(kqReportFieldComInfo.getFieldname())&&leaveRules.size()==0){
          continue;
        }
        title = new HashMap<>();
        String unitType = KQReportBiz.getUnitType(kqReportFieldComInfo, user);
        if(unitType.length()>0){
          title.put("title", SystemEnv.getHtmlLabelNames(kqReportFieldComInfo.getFieldlabel(), user.getLanguage())+ "(" + unitType + ")");
        }else{
          title.put("title", SystemEnv.getHtmlLabelNames(kqReportFieldComInfo.getFieldlabel(), user.getLanguage()));
        }
        title.put("width", 30 * 256);
        this.lsFieldDataKey.add(kqReportFieldComInfo.getFieldname());
        mapChildColumnInfo = this.getChildColumnsInfo(kqReportFieldComInfo.getFieldname(), user);
        childColumns = (List<Object>) mapChildColumnInfo.get("childColumns");
        if (childColumns.size() > 0) {//跨列width取子列的width
          title.put("children", childColumns);
          title.put("colSpan", childColumns.size());
        } else {
          title.put("rowSpan", 3);
        }
        titleList.add(title);

        titleList.addAll(this.getCascadeKeyColumnsInfo(kqReportFieldComInfo.getCascadekey(),user));
      }

      String today = DateUtil.getCurrentDate();
//      if (DateUtil.compDate(today, toDate) > 0) {//结束如期不大于今天
//        toDate = today;
//      }

      if(showColumns.contains("kqCalendar")) {
        childColumns = new ArrayList<>();
        for (String date = fromDate; !isEnd; ) {
          if (date.equals(toDate)) isEnd = true;
          title = new HashMap<>();
          title.put("title", UtilKQ.getWeekDayShort(DateUtil.getWeek(date)-1,user.getLanguage()) +"\r\n"+ DateUtil.geDayOfMonth(date));
          title.put("width", 30 * 256);
          childColumns.add(title);
          cal.setTime(DateUtil.parseToDate(date));
          date = DateUtil.getDate(cal.getTime(), 1);
        }

        title = new HashMap();
        title.put("title", SystemEnv.getHtmlLabelName(386476, user.getLanguage()));
        if (childColumns.size() > 0) {//跨列width取子列的width
          title.put("children", childColumns);
          title.put("colSpan", childColumns.size());
        }
        titleList.add(title);
      }
      sheet.put("titleList", titleList);

      // 没有权限的人最大只支持查询本季
      Map<String, String> getRealDate = new KQReportBiz().realDate(fromDate, toDate, user, "1");
      fromDate = getRealDate.get("fromDate");
      toDate = getRealDate.get("toDate");
      if("-1".equals(fromDate) || "-1".equals(toDate)) {
        retmap.put("status", "1");
        return retmap;
      }

      List<List> paramLists = new ArrayList<>();
      List<Object> paramList = null;
      String forgotBeginWorkCheck_field = " sum(b.forgotBeginWorkCheck) ";

      if(rs.getDBType().equalsIgnoreCase("oracle")) {
        forgotBeginWorkCheck_field = " sum(nvl(b.forgotBeginWorkCheck,0))  ";
      }else if((rs.getDBType()).equalsIgnoreCase("mysql")){
        forgotBeginWorkCheck_field = " sum(ifnull(b.forgotBeginWorkCheck,0)) ";
      }else {
        forgotBeginWorkCheck_field = " sum(isnull(b.forgotBeginWorkCheck,0)) ";
      }

      Map<String,Object> definedFieldInfo = new KQFormatBiz().getDefinedField();
      String definedFieldSum = Util.null2String(definedFieldInfo.get("definedFieldSum"));
      String backFields = " sum(zm.sjycqts) as sjycqts, sum(zm.sjycqss) as sjycqss, sum(zm.sjdksc) as sjdksc,bb.kgtsqz,tt.workdaysbymonth, " +
              " a.id,a.lastname,a.workcode,a.dsporder,b.resourceid,a.subcompanyid1 as subcompanyid,a.departmentid,a.jobtitle," +
              " ufd.tname," +
              " sum(b.workdays) as workdays,sum(b.workMins) as workMins,sum(b.attendancedays) as attendancedays," +
              " sum(b.attendanceMins) as attendanceMins,sum(b.beLate) as beLate,sum(b.beLateMins) as beLateMins, " +
              " sum(b.graveBeLate) as graveBeLate, sum(b.graveBeLateMins) as graveBeLateMins,sum(b.leaveEearly) as leaveEearly," +
              " sum(b.leaveEarlyMins) as leaveEarlyMins, sum(b.graveLeaveEarly) as graveLeaveEarly, " +
              " sum(b.graveLeaveEarlyMins) as graveLeaveEarlyMins,sum(b.absenteeism) as absenteeism, " +
              " sum(b.signdays) as signdays,sum(b.signmins) as signmins, "+
              " sum(b.absenteeismMins) as absenteeismMins, sum(b.forgotCheck)+"+forgotBeginWorkCheck_field+" as forgotCheck "+(definedFieldSum.length()>0?","+definedFieldSum+"":"");
      if(rs.getDBType().equals("oracle")){
        backFields = 	"/*+ index(kq_format_total IDX_KQ_FORMAT_TOTAL_KQDATE) */ "+backFields;
      }
      String sqlFrom = " from hrmresource a JOIN kq_format_total b ON a.id = b.resourceid " +
              "LEFT JOIN uf_custom_holiday tt on tt.groupid=b.groupid \n" +
              "LEFT JOIN uf_kqsjcqjsglb zm ON zm.xm = a.id AND zm.rq = b.kqdate  " +
              "left join uf_first_dept ufd on ufd.deptid=a.departmentid " +
              "left join (\n" +
              "select resourceid,sum(a.kgtsqz)as kgtsqz  from (select  resourceid,CASE  WHEN absenteeismMins IS NULL THEN 0\n" +
              "             WHEN absenteeismMins = 0 THEN 0\n" +
              "             WHEN absenteeismMins / 60.0 <= 3 THEN 0.5\n" +
              "              ELSE  1\n" +
              "               END AS kgtsqz  from kq_format_total\n" +
              "   where  kqdate>='"+fromDate+"' and kqdate<='"+toDate+"' ) a \n" +
              "  group by resourceid ) bb on bb.resourceid= a.id "+
              " WHERE b.kqdate >='" + fromDate + "' and b.kqdate <='" + toDate + "'";
      String sqlWhere = rightSql;
      String groupBy = " group by a.id,a.lastname,a.workcode,a.dsporder,b.resourceid,a.subcompanyid1,a.departmentid,a.jobtitle,ufd.tname,bb.kgtsqz,tt.workdaysbymonth ";
      if (subCompanyId.length() > 0) {
        sqlWhere +=" and a.subcompanyid1 in("+KQReportBiz.splitParamStr(subCompanyId)+") ";
        for(String bean : subCompanyId.split(",")) {
          paramList = new ArrayList<>();
          paramList.add(bean);
          paramLists.add(paramList);
        }
      }

      if (departmentId.length() > 0) {
        sqlWhere +=" and a.departmentid in("+KQReportBiz.splitParamStr(departmentId)+") ";
        for(String bean : departmentId.split(",")) {
          paramList = new ArrayList<>();
          paramList.add(bean);
          paramLists.add(paramList);
        }
      }

      if (resourceId.length() > 0) {
        sqlWhere +=" and a.id in("+KQReportBiz.splitParamStr(resourceId)+") ";
        for(String bean : resourceId.split(",")) {
          paramList = new ArrayList<>();
          paramList.add(bean);
          paramLists.add(paramList);
        }
      }

      if (viewScope.equals("4")) {//我的下属
        if (allLevel.equals("1")) {//所有下属
          sqlWhere += " and a.managerstr like '%," + user.getUID() + ",%'";
        } else {
          sqlWhere += " and a.managerid=" + user.getUID();//直接下属
        }
      }
      if (!"1".equals(isNoAccount)) {
        sqlWhere += " and a.loginid is not null " + (rs.getDBType().equals("oracle") ? "" : " and a.loginid<>'' ");
      }

      if(status.length()>0){
        if (!status.equals("8") && !status.equals("9")) {
          sqlWhere += " and a.status = ?";
          paramList = new ArrayList<>();
          paramList.add(status);
          paramLists.add(paramList);
        }else if (status.equals("8")) {
          sqlWhere += " and (a.status = 0 or a.status = 1 or a.status = 2 or a.status = 3) ";
        }
      }

      String orderBy = " order by a.dsporder asc, a.lastname asc ";
      String descOrderBy = " order by a.dsporder desc, a.lastname desc ";
      sql = "select " + backFields + sqlFrom + sqlWhere + groupBy + orderBy;

      //System.out.println("start" + DateUtil.getFullDate());


      String show_card_source = Util.null2String(kqSettingsComInfo.getMain_val("show_card_source"),"0");//是否显示打卡数据，以及打卡数据来源
      params.put("show_card_source",show_card_source);
      KQOvertimeRulesBiz kqOvertimeRulesBiz = new KQOvertimeRulesBiz();
      int uintType = kqOvertimeRulesBiz.getMinimumUnit();//当前加班单位
      double hoursToDay = kqOvertimeRulesBiz.getHoursToDay();//当前天跟小时计算关系
      params.put("uintType",uintType);
      params.put("hoursToDay",hoursToDay);
      Map<String, Object> flowData = new KQReportBiz().getFlowData(params, user);
      //System.out.println("end" + DateUtil.getFullDate());

      // #1475814-概述：满足考勤报分部部门显示及导出时显示全路径
      String fullPathMainKey = "show_full_path";
      String isShowFullPath = Util.null2String(kqSettingsComInfo.getMain_val(fullPathMainKey),"0");

      RecordSet rsTemp = new RecordSet();
      Map<String, String> workdaysMap = new HashMap<>();
      Map<String, String> sjdkscMap = new HashMap<>();
      rsTemp.execute("SELECT resourceid, sum(workdays) as wk from kq_format_total where kqdate >='"+fromDate+"' and kqdate <='"+toDate+"' group by resourceid ");
      while (rsTemp.next()) {
        String xm = rsTemp.getString("resourceid");
        String wk = rsTemp.getString("wk");
        if (StringUtils.isEmpty(xm)) {
          continue;
        }
        if (StringUtils.isEmpty(wk)) {
          wk = "0";
        }
        workdaysMap.put(xm, wk);
      }
      Map<String, String> ypjcqscMap = new HashMap<>();
      Map<String, String> sjycqtsMap = new HashMap<>();
      rsTemp.execute("select xm, sum(sjycqts) as ts,sum(sjycqss) as ss, sum(sjdksc) as sjdksc from uf_kqsjcqjsglb where rq >= '" + fromDate + "' and rq <= '" + toDate + "' group by xm");
      while (rsTemp.next()) {
        String xm = rsTemp.getString("xm");
        String ts = rsTemp.getString("ts");
        String ss = rsTemp.getString("ss");
        String sjdksc = rsTemp.getString("sjdksc");
        if (StringUtils.isEmpty(ts)) {
          ts = "0";
        }
        if (StringUtils.isEmpty(ss)) {
          ss = "0";
        }
        if (StringUtils.isEmpty(sjdksc)) {
          sjdksc = "0";
        }
        sjycqtsMap.put(xm, ts);
        String wk = workdaysMap.get(xm);
        if (StringUtils.isEmpty(wk) || new BigDecimal(wk).compareTo(BigDecimal.ZERO) == 0) {
          sjdkscMap.put(xm, "0");
        } else {
          BigDecimal wkValue = new BigDecimal(sjdksc).divide(new BigDecimal(wk), 2, RoundingMode.HALF_UP);
          if (wkValue.compareTo(BigDecimal.ZERO) == 0) {
            sjdkscMap.put(xm, "0");
          } else {
            sjdkscMap.put(xm, wkValue.toString());
          }
        }

        if (new BigDecimal(ts).compareTo(new BigDecimal("10")) < 0) {
          ypjcqscMap.put(xm, "0");
        } else {
          BigDecimal fieldValue = new BigDecimal(ss).divide(new BigDecimal(ts), 2, RoundingMode.HALF_UP);
          if (fieldValue.compareTo(BigDecimal.ZERO) == 0) {
            ypjcqscMap.put(xm, "0");
          } else {
            ypjcqscMap.put(xm, fieldValue.toString());
          }
        }
      }
      // 获取公休日
      Map<String, Set<String>> groupIdRqMap = new HashMap<>();
      rsTemp.execute("select groupId, holidayDate from kq_HolidaySet where changeType = 1 and holidayDate>='" + fromDate + "' and holidayDate<='" + toDate + "'");
      while (rsTemp.next()) {
        String groupIdTemp = rsTemp.getString("groupId");
        String holidayDate = rsTemp.getString("holidayDate");
        if (StringUtils.isEmpty(holidayDate) || StringUtils.isEmpty(groupIdTemp)) {
          continue;
        }
        Set<String> dateSet = new HashSet<>();
        if ((!CollectionUtils.isEmpty(groupIdRqMap)) && groupIdRqMap.containsKey(groupIdTemp)) {
          dateSet = groupIdRqMap.get(groupIdTemp);
        }
        dateSet.add(holidayDate);
        groupIdRqMap.put(groupIdTemp, dateSet);
      }

      // 获取补卡次数
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
      Map<String, Set<String>> bdkSetMap = new HashMap<>();
//      rsTemp.execute("select userid, signdate, signtime from hrmschedulesign where signfrom like 'card%' and signfrom != 'card'" +
//              " and signdate >= '" + fromDate + "' and signdate <= '" + toDate + "'");
      String bkSql = "select a.* from \n" +
              "(SELECT a1.yg as userid, a1.kqrq as signdate, a1.bksj as signtime, a2.requestId FROM formtable_main_40_dt1 a1, formtable_main_40 a2 WHERE a1.mainid = a2.id) a,\n" +
              "workflow_requestbase b \n" +
              "WHERE a.requestId = b.requestId and b.currentnodetype = 3 \n" +
              "and a.signdate >= '" + fromDate + "' and a.signdate <= '" + toDate + "'";
      rsTemp.execute(bkSql);
      while (rsTemp.next()) {
        String id = rsTemp.getString("userid");
        String signdate = rsTemp.getString("signdate");
        String signtime = rsTemp.getString("signtime");
        if (StringUtils.isEmpty(id) || StringUtils.isEmpty(signdate) || StringUtils.isEmpty(signtime)) {
          continue;
        }
        if (signtime.length() == 5) {
          signtime = signtime + ":00";
        }
        String keyTemp = id + "_" + signdate;
        Set<String> bdkSet = new HashSet<>();
        if ((!CollectionUtils.isEmpty(bdkSetMap)) && bdkSetMap.containsKey(keyTemp)) {
          bdkSet = bdkSetMap.get(keyTemp);
        }
        LocalTime time = LocalTime.parse(signtime, formatter);
        int hour = time.getHour(); // 提取小时
        bdkSet.add(String.valueOf(hour));
        bdkSetMap.put(keyTemp, bdkSet);
      }
      Map<String, Integer> bdkMap = new HashMap<>();
      for (Map.Entry<String, Set<String>> entry : bdkSetMap.entrySet()) {
        String key = entry.getKey();
        if (StringUtils.isEmpty(key)) {
          continue;
        }
        String ryId = key.split("_")[0];
        int size = 0;
        if ((!CollectionUtils.isEmpty(bdkMap)) && bdkMap.containsKey(ryId)) {
          size = bdkMap.get(ryId);
        }
        Set<String> valueSet = entry.getValue();
        if (!CollectionUtils.isEmpty(valueSet)) {
          if (valueSet.size() <= 2) {
            size = size + valueSet.size();
          } else {
            size = size + 2;
          }
        }
        bdkMap.put(ryId, size);
      }

      // 获取所有离职人员对应最新日期
      Map<String, String> lzrqMap = new HashMap<>();
      rs.execute("SELECT yg, Max(shenxrq) AS ddrq FROM uf_rzjl where bdsj = 3 GROUP BY yg");
      while (rs.next()) {
        String yg = rs.getString("yg");
        String ddrq = rs.getString("ddrq");
        if (StringUtils.isEmpty(yg) || StringUtils.isEmpty(ddrq)) {
          continue;
        }
        lzrqMap.put(yg, ddrq);
      }

      // 获取所有人员当前对应状态
      Map<String, String> ryZtMap = new HashMap<>();
      Map<String, String> ryRzrqMap = new HashMap<>();
      rs.execute("SELECT id, status, companystartdate FROM hrmresource");
      while (rs.next()) {
        String id = rs.getString("id");
        String zt = rs.getString("status");
        String companystartdate = rs.getString("companystartdate");
        if (StringUtils.isEmpty(id)) {
          continue;
        }
        ryZtMap.put(id, zt);
        ryRzrqMap.put(id, companystartdate);
      }
      DateTimeFormatter formatterRq = DateTimeFormatter.ofPattern("yyyy-MM-dd");

      KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();

      HrmScheduleDiffUtil manager = new HrmScheduleDiffUtil();
      QzUtil qzUtil = new QzUtil();
      List<String> allDates = qzUtil.getAllDates(fromDate, toDate);

      // 获取工作日信息
      Set<String> groupIdSet = new HashSet<>();
      Map<String, Set<String>> holidaySetMap = new HashMap<>();
      Map<String, Set<String>> dpgzrdaySetMap = new HashMap<>();
      rs.executeQuery("select holidayDate,changeType,groupId from KQ_HolidaySet where holidayDate >= ? AND holidayDate <= ?", fromDate, toDate);
      while (rs.next()) {
        String holidayDate = rs.getString("holidayDate");
        String changeType = rs.getString("changeType");
        String groupIdTemp = rs.getString("groupId");
        if (StringUtils.isNotEmpty(holidayDate) && StringUtils.isNotEmpty(changeType) && StringUtils.isNotEmpty(groupIdTemp)) {
          BigDecimal changeTypeBd = new BigDecimal(changeType);
          groupIdSet.add(groupIdTemp);
          if (changeTypeBd.compareTo(new BigDecimal("1")) == 0 || changeTypeBd.compareTo(new BigDecimal("3")) == 0) {
            Set<String> holidaySet = new HashSet<>();
            if ((!CollectionUtils.isEmpty(holidaySetMap)) && holidaySetMap.containsKey(groupIdTemp)) {
              holidaySet = holidaySetMap.get(groupIdTemp);
            }
            holidaySet.add(holidayDate);
            holidaySetMap.put(groupIdTemp, holidaySet);
          }
          if (changeTypeBd.compareTo(new BigDecimal("2")) == 0) {
            Set<String> dpgzrdaySet = new HashSet<>();
            if ((!CollectionUtils.isEmpty(dpgzrdaySetMap)) && dpgzrdaySetMap.containsKey(groupIdTemp)) {
              dpgzrdaySet = dpgzrdaySetMap.get(groupIdTemp);
            }
            dpgzrdaySet.add(holidayDate);
            dpgzrdaySetMap.put(groupIdTemp, dpgzrdaySet);
          }
        }
      }

      rs.executeQuery(sql, paramLists);
      int calIndex = -1;
      while (rs.next()) {
        data = new ArrayList<>();
        String id = rs.getString("id");
        for (int fieldDataKeyIdx =0;fieldDataKeyIdx<lsFieldDataKey.size();fieldDataKeyIdx++) {
          String fieldName = lsFieldDataKey.get(fieldDataKeyIdx);
          String fieldid =  KQReportFieldComInfo.field2Id.get(fieldName);
          String fieldValue = "";
          if (fieldName.equals("subcompany")) {
            String tmpSubcompanyId = Util.null2String(rs.getString("subcompanyid"));
            if (tmpSubcompanyId.length() == 0) {
              tmpSubcompanyId = Util.null2String(resourceComInfo.getSubCompanyID(id));
            }

            fieldValue = "1".equals(isShowFullPath) ?
                    SubCompanyComInfo.getSubcompanyRealPath(tmpSubcompanyId, "/", "0") :
                    subCompanyComInfo.getSubCompanyname(tmpSubcompanyId);

            // fieldValue = subCompanyComInfo.getSubCompanyname(tmpSubcompanyId);
          } else if (fieldName.equals("department")) {
            String tmpDepartmentId = Util.null2String(rs.getString("departmentid"));
            if (tmpDepartmentId.length() == 0) {
              tmpDepartmentId = Util.null2String(resourceComInfo.getDepartmentID(id));
            }

            fieldValue = "1".equals(isShowFullPath) ?
                    departmentComInfo.getDepartmentRealPath(tmpDepartmentId, "/", "0") :
                    departmentComInfo.getDepartmentname(tmpDepartmentId);

            // fieldValue = departmentComInfo.getDepartmentname(tmpDepartmentId);
          } else if (fieldName.equals("jobtitle")) {
            String tmpJobtitleId = Util.null2String(rs.getString("jobtitle"));
            if (tmpJobtitleId.length() == 0) {
              tmpJobtitleId = Util.null2String(resourceComInfo.getJobTitle(id));
            }
            fieldValue = jobTitlesComInfo.getJobTitlesname(tmpJobtitleId);
          } else if (fieldName.equals("attendanceSerial")) {
            List<String> serialIds = null;
            if (Util.null2String(jsonObj.get("attendanceSerial")).length() > 0) {
              serialIds = Util.splitString2List(Util.null2String(jsonObj.get("attendanceSerial")), ",");
              for(int i=0;serialIds!=null&&i<serialIds.size();i++){
                data.add(kqReportBiz.getSerialCount(id,fromDate,toDate,serialIds.get(i)));
              }
            }else{
              data.add("");
            }
            continue;
          } else if (fieldName.equals("leave")) {//请假
            List<Map<String, Object>> allLeaveRules = kqLeaveRulesBiz.getAllLeaveRules();
            if (("1").equals(leavetype_is_on)) {
              KQLeaveRulesComInfo kqLeaveRulesComInfo = new KQLeaveRulesComInfo();
              for (int i = allLeaveRules.size() - 1; i >= 0; i--) {
                Map<String, Object> leaveRule = allLeaveRules.get(i);
                String leaveId = Util.null2String(leaveRule.get("id"));
                boolean flag = kqLeaveRulesBiz.filterSubLeaveRule(kqLeaveRulesComInfo, user, leaveId);
                if (flag) {
                  allLeaveRules.remove(i);
                }
              }
            }
            Map<String, Object> leaveRule = null;
            for (int i = 0; allLeaveRules != null && i < allLeaveRules.size(); i++) {
              leaveRule = allLeaveRules.get(i);
              String flowType = Util.null2String("leaveType_" + leaveRule.get("id"));
              String leaveData = Util.null2String(flowData.get(id + "|" + flowType));
              String flowLeaveBackType = Util.null2String("leavebackType_" + leaveRule.get("id"));
              String leavebackData = Util.null2s(Util.null2String(flowData.get(id + "|" + flowLeaveBackType)), "0.0");
              String b_flowLeaveData = "";
              String flowLeaveData = "";
              try {
                //以防止出现精度问题
                if (leaveData.length() == 0) {
                  leaveData = "0.0";
                }
                if (leavebackData.length() == 0) {
                  leavebackData = "0.0";
                }
                BigDecimal b_leaveData = new BigDecimal(leaveData);
                BigDecimal b_leavebackData = new BigDecimal(leavebackData);
                b_flowLeaveData = b_leaveData.subtract(b_leavebackData).toString();
                if(Util.getDoubleValue(b_flowLeaveData, -1) < 0){
                  b_flowLeaveData = "0.0";
                }
              } catch (Exception e) {
                writeLog("GetKQReportCmd:leaveData" + leaveData + ":leavebackData:" + leavebackData + ":" + e);
              }

              if (b_flowLeaveData.length() > 0) {
                flowLeaveData = KQDurationCalculatorUtil.getDurationRound(b_flowLeaveData);
              } else {
                flowLeaveData = KQDurationCalculatorUtil.getDurationRound(Util.null2String(Util.getDoubleValue(leaveData, 0.0) - Util.getDoubleValue(leavebackData, 0.0)));
              }
              data.add(flowLeaveData);
            }
            continue;
          } else if (fieldName.equals("ypjcqsc")) {
            fieldValue = ypjcqscMap.get(id);
            if (StringUtils.isEmpty(fieldValue)) {
              fieldValue = "0";
            }
            String s = sjycqtsMap.get(id);
            if (StringUtils.isEmpty(s) || new BigDecimal(s).compareTo(new BigDecimal("10")) < 0) {
              fieldValue = "0";
            } else {
              String sqltemp = " select resourceid, newleavetype, durationrule, sum(duration) as val,belongdate from hrmresource a, " + KqSplitFlowTypeEnum.LEAVE.getTablename() + " b " +
                      " where a.id = b.resourceid and belongdate >='" + fromDate + "' and belongdate <='" + toDate + "' and b.resourceid = " + id +
                      " group by resourceid, newleavetype, durationrule,belongdate ";
              int qjtstemp = 0;
              rsTemp.execute(sqltemp);
              while (rsTemp.next()) {
                String belongDatetemp = rsTemp.getString("belongdate");
                if (StringUtils.isNotEmpty(belongDatetemp)) {
                  qjtstemp = qjtstemp + 1;
                }
              }
              if (qjtstemp > 10) {
                fieldValue = "0";
              }
            }
            data.add(fieldValue);
            continue;
          } else if (fieldName.equals("ypjdksc")) {
            fieldValue = sjdkscMap.get(id);
            if (StringUtils.isEmpty(fieldValue)) {
              fieldValue = "0";
            }
            data.add(fieldValue);
            continue;
          }  else if (fieldName.equals("dygzrts")) {  // 当月工作日天数
//            User user = new User(Integer.parseInt(id));
//            manager.setUser(user);
            int cnt = 0;
            for (String rqTemp : allDates) {
              String groupId = kqGroupMemberComInfo.getKQGroupId(id, rqTemp);
              if (StringUtils.isEmpty(groupId)) {
                continue;
              }
              if (!CollectionUtils.isEmpty(groupIdSet)) {
                Set<String> holidaySet = holidaySetMap.get(groupId);
                Set<String> dpgzrdaySet = dpgzrdaySetMap.get(groupId);
                if (CollectionUtils.isEmpty(holidaySet) || !holidaySet.contains(rqTemp)) {
                  if ((!CollectionUtils.isEmpty(dpgzrdaySet)) && dpgzrdaySet.contains(rqTemp)) {
                    cnt = cnt + 1;
                  } else {
                    DayOfWeek dayOfWeek = LocalDate.parse(rqTemp).getDayOfWeek();
                    if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
                      cnt = cnt + 1;
                    }
                  }
                }
              } else {
                DayOfWeek dayOfWeek = LocalDate.parse(rqTemp).getDayOfWeek();
                if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
                  cnt = cnt + 1;
                }
              }
            }
            fieldValue = String.valueOf(cnt);
            data.add(fieldValue);
            continue;
          } else if (fieldName.equals("dyfdjrts")) {  // 当月法定假日天数
            int cnt = 0;
            String ryRzrq = ryRzrqMap.get(id);
            String ryZt = ryZtMap.get(id);
            String ryLzrq = lzrqMap.get(id);
            if (StringUtils.isNotEmpty(ryZt) && new BigDecimal(ryZt).compareTo(new BigDecimal("5")) != 0) {
              ryLzrq = null;
            }
            for (String dateTemp : allDates) {
              String groupId = kqGroupMemberComInfo.getKQGroupId(id, dateTemp);
              if (StringUtils.isEmpty(groupId)) {
                continue;
              }
              Set<String> strings = groupIdRqMap.get(groupId);
              if ((!CollectionUtils.isEmpty(strings)) && strings.contains(dateTemp)) {
                if (StringUtils.isEmpty(ryRzrq) || LocalDate.parse(dateTemp, formatterRq).isBefore(LocalDate.parse(ryRzrq, formatterRq))) {
                  continue;
                }
                if (StringUtils.isNotEmpty(ryLzrq) && LocalDate.parse(dateTemp, formatterRq).isAfter(LocalDate.parse(ryLzrq, formatterRq))) {
                  continue;
                }
                cnt = cnt + 1;
              }
            }
            fieldValue = String.valueOf(cnt);
            data.add(fieldValue);
            continue;
          } else if (fieldName.equals("qyjjrts")) {  // 全月节假日天数（不考虑入离职）
            int cnt = 0;
            String groupId = "";
            for (String dateTemp : allDates) {
              groupId = kqGroupMemberComInfo.getKQGroupId(id, dateTemp);
              if (StringUtils.isNotEmpty(groupId)) {
                break;
              }
            }
            if (StringUtils.isNotEmpty(groupId)) {
              Set<String> strings = groupIdRqMap.get(groupId);
              for (String dateTemp : allDates) {
                if ((!CollectionUtils.isEmpty(strings)) && strings.contains(dateTemp)) {
                  cnt = cnt + 1;
                }
              }
            }
            fieldValue = String.valueOf(cnt);
            data.add(fieldValue);
            continue;
          } else if (fieldName.equals("bkcsqz")) {  // 当月法定假日天数
            Integer cnt = bdkMap.get(id);
            if (cnt == null) {
              cnt = 0;
            }
            fieldValue = String.valueOf(cnt);
            data.add(fieldValue);
            continue;
          } else if (fieldName.equals("sjycqss") || fieldName.equals("sjdksc")) {
            fieldValue = Util.null2String(rs.getString(fieldName));
            data.add(fieldValue);
            continue;
          }else if (fieldName.equals("dyzhyggzr")) {  // 当月最后一个工作日日期
//            User user = new User(Integer.parseInt(id));
//            manager.setUser(user);
//            for (int i = allDates.size() - 1; i >= 0; i--) {
//              String s = allDates.get(i);
//              if (manager.getIsWorkday(s)) {
//                fieldValue = s;
//                break;
//              }
//            }
            for (int i = allDates.size() - 1; i >= 0; i--) {
              String rqTemp = allDates.get(i);
              String groupId = kqGroupMemberComInfo.getKQGroupId(id, rqTemp);
              if (StringUtils.isEmpty(groupId)) {
                continue;
              }
              if (!CollectionUtils.isEmpty(groupIdSet)) {
                Set<String> holidaySet = holidaySetMap.get(groupId);
                Set<String> dpgzrdaySet = dpgzrdaySetMap.get(groupId);
                if (CollectionUtils.isEmpty(holidaySet) || !holidaySet.contains(rqTemp)) {
                  if ((!CollectionUtils.isEmpty(dpgzrdaySet)) && dpgzrdaySet.contains(rqTemp)) {
                    fieldValue = rqTemp;
                    break;
                  } else {
                    DayOfWeek dayOfWeek = LocalDate.parse(rqTemp).getDayOfWeek();
                    if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
                      fieldValue = rqTemp;
                      break;
                    }
                  }
                }
              } else {
                DayOfWeek dayOfWeek = LocalDate.parse(rqTemp).getDayOfWeek();
                if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
                  fieldValue = rqTemp;
                  break;
                }
              }
            }
            data.add(fieldValue);
            continue;
          } else if(fieldName.equals("overtime")){
            fieldValue = KQDurationCalculatorUtil.getDurationRound(Util.null2String(flowData.get(id + "|workingDayOvertime_nonleave")));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("workingDayOvertime_nonleave"))));

            fieldValue = KQDurationCalculatorUtil.getDurationRound(Util.null2String(flowData.get(id + "|restDayOvertime_nonleave")));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("restDayOvertime_nonleave"))));

            fieldValue = KQDurationCalculatorUtil.getDurationRound(Util.null2String(flowData.get(id + "|holidayOvertime_nonleave")));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("holidayOvertime_nonleave"))));

            fieldValue = KQDurationCalculatorUtil.getDurationRound(Util.null2String(flowData.get(id + "|workingDayOvertime_4leave")));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("workingDayOvertime_4leave"))));

            fieldValue = KQDurationCalculatorUtil.getDurationRound(Util.null2String(flowData.get(id + "|restDayOvertime_4leave")));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("restDayOvertime_4leave"))));

            fieldValue = KQDurationCalculatorUtil.getDurationRound(Util.null2String(flowData.get(id + "|holidayOvertime_4leave")));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("holidayOvertime_4leave"))));

            double workingDayOvertime_4leave = Util.getDoubleValue(Util.null2String(flowData.get(id+"|workingDayOvertime_4leave")));
            workingDayOvertime_4leave = workingDayOvertime_4leave<0?0:workingDayOvertime_4leave;
            double restDayOvertime_4leave = Util.getDoubleValue(Util.null2String(flowData.get(id+"|restDayOvertime_4leave")));
            restDayOvertime_4leave = restDayOvertime_4leave<0?0:restDayOvertime_4leave;
            double holidayOvertime_4leave = Util.getDoubleValue(Util.null2String(flowData.get(id+"|holidayOvertime_4leave")));
            holidayOvertime_4leave = holidayOvertime_4leave<0?0:holidayOvertime_4leave;

            double workingDayOvertime_nonleave = Util.getDoubleValue(Util.null2String(flowData.get(id+"|workingDayOvertime_nonleave")));
            workingDayOvertime_nonleave = workingDayOvertime_nonleave<0?0:workingDayOvertime_nonleave;
            double restDayOvertime_nonleave = Util.getDoubleValue(Util.null2String(flowData.get(id+"|restDayOvertime_nonleave")));
            restDayOvertime_nonleave = restDayOvertime_nonleave<0?0:restDayOvertime_nonleave;
            double holidayOvertime_nonleave = Util.getDoubleValue(Util.null2String(flowData.get(id+"|holidayOvertime_nonleave")));
            holidayOvertime_nonleave = holidayOvertime_nonleave<0?0:holidayOvertime_nonleave;
            fieldValue = KQDurationCalculatorUtil.getDurationRound(String.valueOf(workingDayOvertime_4leave+restDayOvertime_4leave+holidayOvertime_4leave+
                    workingDayOvertime_nonleave+restDayOvertime_nonleave+holidayOvertime_nonleave));
            data.add(getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(KQReportFieldComInfo.field2Id.get("overtimeTotal"))));
            continue;
          }else if(fieldName.equals("businessLeave") || fieldName.equals("officialBusiness")){
            String businessLeaveData = Util.null2s(Util.null2String(flowData.get(id+"|"+fieldName)),"0.0");
            String backType = fieldName+"_back";
            String businessLeavebackData = Util.null2s(Util.null2String(flowData.get(id+"|"+backType)),"0.0");
            String businessLeave = "";
            try{
              //以防止出现精度问题
              if(businessLeaveData.length() == 0){
                businessLeaveData = "0.0";
              }
              if(businessLeavebackData.length() == 0){
                businessLeavebackData = "0.0";
              }
              BigDecimal b_businessLeaveData = new BigDecimal(businessLeaveData);
              BigDecimal b_businessLeavebackData = new BigDecimal(businessLeavebackData);
              businessLeave = b_businessLeaveData.subtract(b_businessLeavebackData).toString();
              if(Util.getDoubleValue(businessLeave, -1) < 0){
                businessLeave = "0.0";
              }
            }catch (Exception e){
            }
            fieldValue = KQDurationCalculatorUtil.getDurationRound(businessLeave);
          } else if(Util.null2String(kqReportFieldComInfo.getCascadekey(fieldid)).length()>0){
            fieldValue = Util.formatMultiLang(Util.null2String(rs.getString(fieldName)),""+user.getLanguage());
            data.add(fieldValue);

            List<String> lsCascadekey = Util.splitString2List(kqReportFieldComInfo.getCascadekey(fieldid),",");
            for(int i=0;i<lsCascadekey.size();i++){
              if(Util.null2String(rs.getString(lsCascadekey.get(i))).length()>0){
                fieldid =  KQReportFieldComInfo.field2Id.get(lsCascadekey.get(i));
                fieldValue = getFieldValueByUnitType(rs.getString(lsCascadekey.get(i)),kqReportFieldComInfo.getUnittype(fieldid));
              }else{
                fieldValue = "0";
              }
              data.add(fieldValue);
            }
            continue;
          }else {
            fieldValue = Util.formatMultiLang(Util.null2String(rs.getString(fieldName)),""+user.getLanguage());
            fieldValue = getFieldValueByUnitType(fieldValue,kqReportFieldComInfo.getUnittype(fieldid));
          }
          fieldValue = Util.formatMultiLang(fieldValue,""+user.getLanguage());
          data.add(fieldValue);
        }

        List<Object> amData = Lists.newArrayList();
        List<Object> pmData = Lists.newArrayList();
        if(isKqReportHalfOpen) {
          amData.addAll(data);
          pmData.addAll(data);
          calIndex = data.size();
        }

        if(showColumns.contains("kqCalendar")) {
//          Map<String, Object> detialDatas = kqReportBiz.getDetialDatas(id, fromDate, toDate, user,flowData,true);
          Map<String, Object> detialDatas = kqReportBiz.getDetialDatas(id, fromDate, toDate, user,flowData,true,uintType,show_card_source);
          String user_endDate = Util.null2String(resourceComInfo.getEndDate(id));
          String user_status = Util.null2String(resourceComInfo.getStatus(id));
          String begindate = Util.null2String(resourceComInfo.getCreatedate(id)).trim();
          String companyStartDate = Util.null2String(resourceComInfo.getCompanyStartDate(id)).trim();
          if(companyStartDate.length()!=10){
            companyStartDate = "";
          }
          if(companyStartDate.length()>0 && companyStartDate.indexOf("-")>0){
            begindate=companyStartDate;
          }
          isEnd = false;
          for (String date = fromDate; !isEnd; ) {
            if (date.equals(toDate)) isEnd = true;
            if(DateUtil.compDate(today, date)>0){
              if(isKqReportHalfOpen) {
                amData.add("");
                pmData.add("");
              } else {
                data.add("");
              }
            }else{
              if(!(user_status.equals("0")||user_status.equals("1")||user_status.equals("2")||user_status.equals("3"))){
                //其他状态
                if(user_endDate.length()>0  && date.compareTo(user_endDate)>0){//人员合同结束日期之后
                  if(isKqReportHalfOpen) {
                    amData.add("");
                    pmData.add("");
                  } else {
                    data.add("");
                  }
                  cal.setTime(DateUtil.parseToDate(date));
                  date = DateUtil.getDate(cal.getTime(), 1);
                  continue;
                }
              }
              if(begindate.length()>0 && date.compareTo(begindate)<0 ){//人员入职日期前无需计算考勤，如果没有入职日期，已创建日期为准
                if(isKqReportHalfOpen) {
                  amData.add("");
                  pmData.add("");
                } else {
                  data.add("");
                }
                cal.setTime(DateUtil.parseToDate(date));
                date = DateUtil.getDate(cal.getTime(), 1);
                continue;
              }
              if (detialDatas.get(id + "|" + date) != null) {
                if(isKqReportHalfOpen) {
                  amData.add(((Map<String, Object>) detialDatas.get(id + "|" + date)).get("textAM"));
                  pmData.add(((Map<String, Object>) detialDatas.get(id + "|" + date)).get("textPM"));
                } else {
                  data.add(((Map<String, Object>) detialDatas.get(id + "|" + date)).get("text"));
                }
              } else {
                if(isKqReportHalfOpen) {
                  amData.add(SystemEnv.getHtmlLabelName(26593, user.getLanguage()));
                  pmData.add(SystemEnv.getHtmlLabelName(26593, user.getLanguage()));
                } else {
                  data.add(SystemEnv.getHtmlLabelName(26593, user.getLanguage()));
                }
              }
            }
            cal.setTime(DateUtil.parseToDate(date));
            date = DateUtil.getDate(cal.getTime(), 1);
          }
        }
        if(isKqReportHalfOpen) {
          dataList.add(amData);
          dataList.add(pmData);
        } else {
          dataList.add(data);
        }
      }
      sheet.put("dataList", dataList);
      if(isKqReportHalfOpen) {
        sheet.put("calIndex", calIndex);
      }
      sheet.put("constraintList", constraintList);
      sheet.put("createFile", "1");
      lsSheet.add(sheet);

      workbook.put("sheet", lsSheet);
      String fileName = SystemEnv.getHtmlLabelName(390351, user.getLanguage())+" "+fromDate+" "+toDate;
      workbook.put("fileName", fileName);
      ExcelUtil ExcelUtil = new ExcelUtil();
      Map<String, Object> exportMap = ExcelUtil.export(workbook, request, response,true);
      retmap.putAll(exportMap);
      retmap.put("status", "1");
    } catch (Exception e) {
      retmap.put("status", "-1");
      retmap.put("message", SystemEnv.getHtmlLabelName(382661, user.getLanguage()));
      writeLog(e);
    }
    return retmap;
  }

  private Map<String, Object> getChildColumnsInfo(String parentid, User user) {
    Map<String, Object> returnMap = new HashMap<>();
    List<Object> titleList = new ArrayList<>();
    Map<String, Object> title = null;
    KQSettingsComInfo kqSettingsComInfo = new KQSettingsComInfo();
    String leavetype_is_on = Util.null2String(kqSettingsComInfo.getMain_val("leavetype_is_on"),"0");
    if (parentid.equals("attendanceSerial")) {//考勤班次
      KQShiftManagementComInfo kqShiftManagementComInfo = new KQShiftManagementComInfo();
      JSONObject jsonObj = JSON.parseObject(Util.null2String(params.get("data")));
      List<String> serialIds = null;
      if (Util.null2String(jsonObj.get("attendanceSerial")).length() > 0) {
        serialIds = Util.splitString2List(Util.null2String(jsonObj.get("attendanceSerial")), ",");
      }
      for (int i = 0; serialIds != null && i < serialIds.size(); i++) {
        title = new HashMap<>();
        title.put("title", Util.formatMultiLang(kqShiftManagementComInfo.getSerial(serialIds.get(i)),""+user.getLanguage()));
        title.put("width", 30 * 256);
        titleList.add(title);
      }
    } else if (parentid.equals("leave")) {
      KQLeaveRulesBiz kqLeaveRulesBiz = new KQLeaveRulesBiz();
      List<Map<String, Object>> leaveRules = kqLeaveRulesBiz.getAllLeaveRules();
      if (("1").equals(leavetype_is_on)) {
        KQLeaveRulesComInfo kqLeaveRulesComInfo = new KQLeaveRulesComInfo();
        for (int i = leaveRules.size() - 1; i >= 0; i--) {
          Map<String, Object> leaveRule = leaveRules.get(i);
          String leaveId = Util.null2String(leaveRule.get("id"));
          boolean flag = kqLeaveRulesBiz.filterSubLeaveRule(kqLeaveRulesComInfo, user, leaveId);
          if (flag) {
            leaveRules.remove(i);
          }
        }
      }
      for (int i = 0; leaveRules != null && i < leaveRules.size(); i++) {
        Map<String, Object> leaveRule = leaveRules.get(i);
        String name = Util.formatMultiLang(Util.null2String(leaveRule.get("name")),""+user.getLanguage());
        String unitType = Util.null2String(leaveRule.get("unitType"));
        String unitName = (KQUnitBiz.isLeaveHour(unitType)) ? SystemEnv.getHtmlLabelName(391, user.getLanguage()) : SystemEnv.getHtmlLabelName(1925, user.getLanguage());
        title = new HashMap<>();
        title.put("title", name + "(" + unitName + ")");
        title.put("width", 30 * 256);
        titleList.add(title);
      }
    }else if(parentid.equals("overtime")){
      String[] overtimeChild = {"overtime_nonleave","overtime_4leave","overtimeTotal"};
      for(int i=0;i<overtimeChild.length;i++){
        String id = overtimeChild[i];
        title = new HashMap();
        String fieldlabel = "";
        if("overtime_nonleave".equalsIgnoreCase(id)){
          fieldlabel = "125805";
          title.put("title", SystemEnv.getHtmlLabelNames(fieldlabel, user.getLanguage()));
          title.put("rowSpan","2");
        }else if("overtime_4leave".equalsIgnoreCase(id)){
          fieldlabel = "125804";
          title.put("title", SystemEnv.getHtmlLabelNames(fieldlabel, user.getLanguage()));
          title.put("rowSpan","2");
        }else{
          fieldlabel = "523";
          title.put("showDetial","1");
          String unitType = (KQOvertimeRulesBiz.getMinimumUnit()==3 || KQOvertimeRulesBiz.getMinimumUnit()==5 ||KQOvertimeRulesBiz.getMinimumUnit()==6)?"2":"1";
          String unitTypeName = "";
          if(Util.null2String(unitType).length()>0){
            if(unitType.equals("1")){
              unitTypeName=SystemEnv.getHtmlLabelName(1925, user.getLanguage());
            }else if(unitType.equals("2")){
              unitTypeName=SystemEnv.getHtmlLabelName(391, user.getLanguage());
            }else if(unitType.equals("3")){
              unitTypeName=SystemEnv.getHtmlLabelName(18083, user.getLanguage());
            }
          }
          title.put("title", SystemEnv.getHtmlLabelNames(fieldlabel, user.getLanguage())+ "(" + unitTypeName + ")");
        }

        Map<String,Object> mapChildColumnInfo = getChildColumnsInfo(id, user);
        int childWidth = 65;
        List<Object> childColumns = (List<Object>)mapChildColumnInfo.get("childColumns");
        if(childColumns.size()>0) {//跨列width取子列的width
          title.put("children", childColumns);
          childWidth = Util.getIntValue(Util.null2String(mapChildColumnInfo.get("sumChildColumnWidth")),65);
        }
        title.put("width", childWidth+"");
        titleList.add(title);
      }
    } else {
      KQReportFieldComInfo kqReportFieldComInfo = new KQReportFieldComInfo();
      while (kqReportFieldComInfo.next()) {
        if (kqReportFieldComInfo.getParentid().equals(parentid)) {
          if(!kqReportFieldComInfo.getReportType().equals("month"))continue;
          title = new HashMap<>();
          title.put("title", SystemEnv.getHtmlLabelNames(kqReportFieldComInfo.getFieldlabel(), user.getLanguage()) + "(" + KQReportBiz.getUnitType(kqReportFieldComInfo, user) + ")");
          title.put("width", 30 * 256);
          titleList.add(title);
        }
      }
    }
    returnMap.put("childColumns", titleList);
    return returnMap;
  }

  private List<Object>  getCascadeKeyColumnsInfo(String cascadeKey, User user){
    List<Object> titleList = new ArrayList<>();
    Map<String, Object> title = null;
    if(Util.null2String(cascadeKey).length()==0){
      return titleList;
    }
    List<String> lsCascadeKey = Util.splitString2List(cascadeKey,",");
    KQReportFieldComInfo kqReportFieldComInfo = new KQReportFieldComInfo();
    for(int i=0;i<lsCascadeKey.size();i++){
      kqReportFieldComInfo.setTofirstRow();
      while (kqReportFieldComInfo.next()) {
        if(!kqReportFieldComInfo.getReportType().equals("month"))continue;
        if (kqReportFieldComInfo.getFieldname().equals(lsCascadeKey.get(i))){
          title = new HashMap<>();
          title.put("title", SystemEnv.getHtmlLabelNames(kqReportFieldComInfo.getFieldlabel(), user.getLanguage()) + "(" + KQReportBiz.getUnitType(kqReportFieldComInfo, user) + ")");
          title.put("width", 30 * 256);

          titleList.add(title);
        }
      }
    }
    return titleList;
  }

  private String getFieldValueByUnitType(String fieldValue,String unittype){
    if (Util.null2String(unittype).length() > 0) {
      if (fieldValue.length() == 0) {
        fieldValue = "0";
      } else {
        if (unittype.equals("2")) {
          fieldValue = KQDurationCalculatorUtil.getDurationRound(("" + (Util.getDoubleValue(fieldValue) / 60.0)));
        }
      }
    }
    return fieldValue;
  }
  @Override
  public BizLogContext getLogContext() {
    return null;
  }
}
